#ifndef MSGD_TIMER_H
#define MSGD_TIMER_H 1

#include <config.h>
#include <core.h>

#define MSGD_TIMER_INFINITE  (msgd_int_t)-1
#define MSGD_MAX_DELAY_TIME  300


extern msgd_rbtree_t     msgd_event_timer_rbtree;
extern pthread_mutex_t               *msgd_event_timer_mutex; 

#ifdef __plusplus
extern "C" {
#endif 

msgd_int_t    msgd_event_timer_init(void);
msgd_uint_t   msgd_event_find_timer(void); 
void          msgd_expire_timers(void);

static inline void msgd_event_del_timer(msgd_event_t *ev)
{

   DEBUG("timer event del %d :%d",msgd_event_ident(ev),ev->timer.key);
   msgd_mutex_lock(msgd_event_timer_mutex);
   msgd_rbtree_insert(&msgd_event_timer_rbtree,&ev->timer);
   msgd_mutex_unlock(msgd_event_timer_mutex);

   ev->timer_set = 0;
}


static inline void msgd_event_add_timer(msgd_event_t *ev,msgd_uint_t timer)
{
   msgd_uint_t key;
   msgd_int_t  diff;
  
   key = msgd_current_msec + timer;

   if(ev->timer_set){

      diff = (msgd_int_t)(key - ev->timer.key);
   
      if(msgd_abs(diff) < MSGD_MAX_DELAY_TIME){
         DEBUG("event timer: %d, old: %d, new: %d",msgd_event_ident(ev),ev->timer.key,key);
         return ;
      }

      msgd_event_del_timer(ev);
   } 

   ev->timer.key = key;
   DEBUG("event timer add %d %d:%d",msgd_event_ident(ev),timer,ev->timer.key);

   msgd_mutex_lock(msgd_event_timer_mutex);
   msgd_rbtree_insert(&msgd_event_timer_rbtree,&ev->timer);
   msgd_mutex_unlock(msgd_event_timer_mutex);

   ev->timer_set = 1;
}

#ifdef __plusplus
}
#endif

#endif //MSGD_TIMER_H
